#include "cem/boundary_condition.h"
#include "cem/electromagnetics_system.h"
#include "cem/material_database.h"
#include "cem/mesh_manager.h"
#include "cem/parameter_reader.h"

#include <libmesh/dirichlet_boundaries.h>
#include <libmesh/dof_map.h>
#include <libmesh/enum_order.h>
#include <libmesh/equation_systems.h>
#include <libmesh/fe_type.h>
#include <libmesh/linear_implicit_system.h>
#include <libmesh/mesh.h>
#include <libmesh/zero_function.h>

namespace cem
{

// 函数: initialize
// 作用: 创建 EquationSystems 与线性系统，添加变量与边界条件，并缓存参数
void
ElectromagneticsSystem::initialize(const ParameterReader & params,
                                   const MeshManager & mesh,
                                   const MaterialDatabase & /*materials*/,
                                   const BoundaryConditionManager & bcs)
{
    using namespace libMesh;

    // 构建 EquationSystems 并添加线性隐式系统
    _equation_systems = std::make_unique<EquationSystems>(const_cast<Mesh &>(mesh.get_mesh()));
    auto & sys = _equation_systems->add_system<LinearImplicitSystem>(_system_name);

    // 添加一个 HCurl 向量变量：u（复数 Number 类型）
    _var = sys.add_variable("u", FIRST, NEDELEC_ONE);

    // 初始化 system（分配矩阵/向量等）
    _equation_systems->init();

    // 缓存边界条件规格（供装配阶段构造边界型右端项）
    _boundary_specs = bcs.specs();

    // 频率到角频率（若 FREQUENCY 列表存在则取第一个作为当前频率）
    _omega = 0.0;
    const auto & freqs = params.get_frequencies();
    if (!freqs.empty())
        _omega = 2.0 * cem::constants::pi * freqs.front();

    _layers = params.get_layers();

    // 初始化集中式材料管理器，并基于当前网格构建子域张量缓存
    // 默认采用 LegacyMapMaterialLaw 实现，后续可通过 set_material_law 切换
    _material_manager.initialize(*this, params, nullptr);
}

// 函数: name
std::string
ElectromagneticsSystem::name() const
{
    return "electromagnetics_system";
}

// 访问 EquationSystems（可写）
libMesh::EquationSystems &
ElectromagneticsSystem::equation_systems()
{
    return *_equation_systems;
}

// 访问 EquationSystems（只读）
const libMesh::EquationSystems &
ElectromagneticsSystem::equation_systems() const
{
    return *_equation_systems;
}

// 访问线性隐式系统（可写）
libMesh::LinearImplicitSystem &
ElectromagneticsSystem::linear_system()
{
    return _equation_systems->get_system<libMesh::LinearImplicitSystem>(_system_name);
}

// 访问线性隐式系统（只读）
const libMesh::LinearImplicitSystem &
ElectromagneticsSystem::linear_system() const
{
    return _equation_systems->get_system<libMesh::LinearImplicitSystem>(_system_name);
}

} // namespace cem